﻿#pragma once

#include "MessageQueue.h"
#include "../Shared/Functions/IniReader.h"
#include "../Shared/Data/Notice.h"
#include "../Shared/BaseStats.h"
#include "../Shared/Data/ItemData.h"
#include "MirDatabase/MineInfo.h"
#include "MirObjects/GuildObject.h"
#include "../Shared/Data/GuildData.h"
#include <string>
#include <vector>
#include <stdexcept>
#include <any>
#include "../stringhelper.h"
#include "../tangible_filesystem.h"

using namespace Server::MirDatabase;
using namespace Server::MirObjects;

namespace Server
{
    class Settings final
    {
    private:
        static long long GroupInviteDelay;
        static long long TradeDelay;

        static Server::MessageQueue *getMessageQueue();

    public:
        static constexpr int Day = 24 * Hour, Hour = 60 * Minute, Minute = 60 * Second, Second = 1000;

        static const std::string EnvirPath;
        static const std::string ConfigPath;
        static const std::string MapPath;
        static const std::string ExportPath;
        static const std::string GuildPath;
        static const std::string ConquestsPath;
        static const std::string NPCPath;
        static const std::string GoodsPath;
        static const std::string RecipePath;
        static const std::string QuestPath;
        static const std::string DropPath;
        static const std::string RoutePath;
        static const std::string NameListPath;
        static const std::string ValuePath;
        static const std::string NoticePath;

    private:
        static InIReader *const Reader;

    public:
        static Notice *Notice;

        //General
        static std::string VersionPath;
        static bool CheckVersion;
        static std::vector<std::vector<unsigned char>> VersionHashes;
        static std::string GMPassword;
        static bool Multithreaded;
        static int ThreadLimit;
        static bool TestServer;
        static bool EnforceDBChecks;

        static bool MonsterProcessWhenAlone;
        static bool MonsterProcessWhenStacked;

        static std::string DefaultNPCFilename;
        static std::string MonsterNPCFilename;
        static std::string RobotNPCFilename;
        static std::string FishingDropFilename;
        static std::string AwakeningDropFilename;
        static std::string StrongboxDropFilename;
        static std::string BlackstoneDropFilename;

        //Network
        static std::string IPAddress;

        static unsigned short Port;
        static unsigned short TimeOut;
        static unsigned short MaxUser;
        static unsigned short RelogDelay;
        static unsigned short MaxIP;

        //HTTP
        static bool StartHTTPService;
        static std::string HTTPIPAddress;
        static std::string HTTPTrustedIPAddress;

        //Permission
        static bool AllowNewAccount;
        static bool AllowChangePassword;
        static bool AllowLogin;
        static bool AllowNewCharacter;
        static bool AllowDeleteCharacter;
        static bool AllowStartGame;
        static bool AllowCreateAssassin;
        static bool AllowCreateArcher;

        static int AllowedResolution;

        //Optional
        static bool SafeZoneBorder;
        static bool SafeZoneHealing;
        static bool GameMasterEffect;
        static bool GatherOrbsPerLevel;
        static bool ExpMobLevelDifference;
        static int LineMessageTimer;

        //Database
        static int SaveDelay;
        static short CredxGold;

        //Game
        static std::vector<long long> ExperienceList;
        static std::vector<long long> OrbsExpList;
        static std::vector<long long> OrbsDefList;
        static std::vector<long long> OrbsDmgList;

        static float DropRate;
        static float ExpRate;

        static int ItemTimeOut;
        static int PlayerDiedItemTimeOut;
        static int DropRange;
        static int DropStackSize;
        static int PKDelay;

        static bool PetSave;

        static int RestedPeriod;
        static int RestedBuffLength;
        static int RestedExpBonus;
        static int RestedMaxBonus;

        static std::string SkeletonName;
        static std::string ShinsuName;
        static std::string BugBatName;
        static std::string Zuma1;
        static std::string Zuma2;
        static std::string Zuma3;
        static std::string Zuma4;
        static std::string Zuma5;
        static std::string Zuma6;
        static std::string Zuma7;
        static std::string Turtle1;
        static std::string Turtle2;
        static std::string Turtle3;
        static std::string Turtle4;
        static std::string Turtle5;
        static std::string BoneMonster1;
        static std::string BoneMonster2;
        static std::string BoneMonster3;
        static std::string BoneMonster4;
        static std::string BehemothMonster1;
        static std::string BehemothMonster2;
        static std::string BehemothMonster3;
        static std::string HellKnight1;
        static std::string HellKnight2;
        static std::string HellKnight3;
        static std::string HellKnight4;
        static std::string HellBomb1;
        static std::string HellBomb2;
        static std::string HellBomb3;
        static std::string WhiteSnake;
        static std::string AngelName;
        static std::string BombSpiderName;
        static std::string CloneName;
        static std::string AssassinCloneName;
        static std::string VampireName;
        static std::string ToadName;
        static std::string SnakeTotemName;
        static std::string SnakesName;
        static std::string AncientBatName;
        static std::string TucsonGeneralEgg;
        static std::string GeneralMeowMeowMob1;
        static std::string GeneralMeowMeowMob2;
        static std::string GeneralMeowMeowMob3;
        static std::string GeneralMeowMeowMob4;

        static std::string HealRing;
        static std::string FireRing;
        static std::string ParalysisRing;
        static std::string BlinkSkill;

        static std::string PKTownMapName;
        static int PKTownPositionX;
        static int PKTownPositionY;

        static unsigned int MaxDropGold;
        static bool DropGold;


        //IntelligentCreature      
        static std::string CreatureBlackStoneName;

        //Fishing Settings
        static int FishingAttempts;
        static int FishingSuccessStart;
        static int FishingSuccessMultiplier;
        static long long FishingDelay;
        static int FishingMobSpawnChance;
        static std::string FishingMonster;

        //Mail Settings
        static bool MailAutoSendGold;
        static bool MailAutoSendItems;
        static bool MailFreeWithStamp;
        static unsigned int MailCostPer1KGold;
        static unsigned int MailItemInsurancePercentage;
        static unsigned int MailCapacity;

        //Refine Settings
        static bool OnlyRefineWeapon;
        static unsigned char RefineBaseChance;
        static int RefineTime;
        static unsigned char RefineIncrease;
        static unsigned char RefineCritChance;
        static unsigned char RefineCritIncrease;
        static unsigned char RefineWepStatReduce;
        static unsigned char RefineItemStatReduce;
        static int RefineCost;

        static std::string RefineOreName;

        //Marriage Settings
        static int LoverEXPBonus;
        static int MarriageCooldown;
        static bool WeddingRingRecall;
        static int MarriageLevelRequired;
        static int ReplaceWedRingCost;

        //Mentor Settings
        static unsigned char MentorLevelGap;
        static bool MentorSkillBoost;
        static unsigned char MentorLength;
        static unsigned char MentorDamageBoost;
        static unsigned char MentorExpBoost;
        static unsigned char MenteeExpBank;

        //Gem Settings
        static bool GemStatIndependent;


        //Goods Settings
        static bool GoodsOn;
        static unsigned int GoodsMaxStored;
        static unsigned int GoodsBuyBackTime;
        static unsigned int GoodsBuyBackMaxStored;
        static bool GoodsHideAddedStats;

        static std::vector<BaseStats*> ClassBaseStats;

        static std::vector<RandomItemStat*> RandomItemStatsList;
        static std::vector<MineSet*> MineSetList;

        //item related settings
        static unsigned char MagicResistWeight;
        static unsigned char PoisonResistWeight;
        static unsigned char CriticalRateWeight;
        static unsigned char CriticalDamageWeight;
        static unsigned char FreezingAttackWeight;
        static unsigned char PoisonAttackWeight;
        static unsigned char HealthRegenWeight;
        static unsigned char ManaRegenWeight;
        static unsigned char MaxLuck;

        static bool PvpCanResistMagic;
        static bool PvpCanResistPoison;
        static bool PvpCanFreeze;

        static unsigned char RangeAccuracyBonus;

        //Guild related settings
        static unsigned char Guild_RequiredLevel;
        static unsigned char Guild_PointPerLevel;
        static float Guild_ExpRate;
        static unsigned int Guild_WarCost;
        static long long Guild_WarTime;

        static std::vector<GuildItemVolume*> Guild_CreationCostList;
        static std::vector<long long> Guild_ExperienceList;
        static std::vector<int> Guild_MembercapList;
        static std::vector<GuildBuffInfo*> Guild_BuffList;
        static long long getGroupInviteDelay();
        static void setGroupInviteDelay(long long value);
        static long long getTradeDelay();
        static void setTradeDelay(long long value);

        static void LoadVersion();

        static void Load();

        static void LoadNotice();

        static void Save();

        static void LoadEXP();

        static void LoadBaseStats();

        static void SaveBaseStats(std::vector<BaseStats*> &classStats = std::vector<BaseStats*>());

        static void LoadRandomItemStats();
        static void SaveRandomItemStats();

        static void LoadMines();
        static void SaveMines();

        static void LoadGuildSettings();
        static void SaveGuildSettings();
        static void LinkGuildCreationItems(std::vector<ItemInfo*> &ItemList);

        static void LoadAwakeAttribute();
        static void SaveAwakeAttribute();

        static void LoadFishing();
        static void SaveFishing();

        static void LoadMail();
        static void SaveMail();

        static void LoadRefine();
        static void SaveRefine();

        static void LoadMarriage();
        static void SaveMarriage();

        static void LoadMentor();
        static void SaveMentor();
        static void LoadGem();
        static void SaveGem();

        static void LoadGoods();
        static void SaveGoods();

    };
}
